home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / daymisckit_proj / daymisckit-1 / DAYLogFile.m < prev    next >
Text File  |  1995-06-12  |  5KB  |  223 lines

  1. //
  2. //    DAYLockFile.h -- a generic class to simplify keeping an atomic lock file
  3. //        Written by Don Yacktman (c) 1993 by Don Yacktman.
  4. //                Version 1.0.  All rights reserved.
  5. //
  6. //        This is a free object!  Contact the author for the latest version.
  7. //        Don Yacktman, 4279 N. Ivy Lane, Provo, UT, 84604
  8. //        e-mail:  Don_Yacktman@byu.edu
  9. //
  10. //        You may use and copy this class freely as long as you
  11. //        comply with the following terms:
  12. //            (1) Do not remove the author's name or any of the
  13. //                copyright notices from this file.
  14. //            (2) If you redistribute an application which uses this
  15. //                object, you must either include the source code for
  16. //                this object with the application or state in your
  17. //                application's documentation that you (a) use this
  18. //                object and (b) where to obtain the source code for
  19. //                the object.
  20. //            (3) In no way shall the author or his employer(s) be held
  21. //                responsible for any damages caused by what this object
  22. //                does or does not do.
  23. //            (4) You have no warranty whatsoever that this object is
  24. //                good for any purpose at all.  If you find it useful
  25. //                for something, consider yourself lucky and leave it at that.
  26. //
  27.  
  28.     // *****  denotes an unfinished/unimplemented method.
  29.  
  30. #import <daymisckit/daymisckit.h>
  31. #import <stdio.h>
  32.  
  33. @interface DAYLogFile(private)
  34.  
  35. - _newLine;    // forces the log to start without any history.
  36. - _printRepeats; // "Last line repeated x times."
  37.  
  38. @end
  39.  
  40. @implementation DAYLogFile
  41.  
  42. - init
  43. {
  44.     id ret = [super init];
  45.     fileOpen = NO; special = NO;
  46.     return ret;
  47. }
  48.  
  49. - fileName { return fileName; }
  50. - setFileName:aString
  51. {
  52.     if (fileOpen) [self closeFile];
  53.     [lockFile free];
  54.     lockFile = nil;
  55.     special = NO;
  56.     fileName = aString;
  57.     return self;
  58. }
  59.  
  60. - setLockFile:newLockFile
  61. {
  62.     [lockFile free];
  63.     lockFile = newLockFile;
  64.     return self;
  65. }
  66.  
  67. - (BOOL)addLineToLogFile:aString
  68. {
  69.     if (![self openFile]) return NO;
  70.     if (![self appendToLogFile:aString andFlush:NO]) return NO;
  71.     if (![self closeFile]) return NO;
  72.     return YES;
  73. }
  74.  
  75. - _newLine    // forces the log to start without any history.
  76. {
  77.     repeats = 0;
  78.     if (lastLine) {
  79.         [lastLine free]; lastLine = nil;
  80.     }
  81.     return self;
  82. }
  83.  
  84. - (BOOL)openFile
  85. {
  86.     if (special) return YES;    // stdin and stdout are open already
  87.     if (fileOpen) return YES;    // file is already open
  88.     if (lockFile) if (![lockFile lock]) return NO; // lock if needed
  89.     file = fopen([fileName stringValue], "a");    // do the open
  90.     if (!file) return NO;
  91.     fileOpen = YES;
  92.     [self _newLine];
  93.     return YES;
  94. }
  95.  
  96. - (BOOL)closeFile
  97. {
  98.     if (special) return YES;    // don't close stdin or stdout
  99.     if (!fileOpen) return NO;    // can't close an unopened file
  100.     [self _printRepeats];
  101.     fclose(file);
  102.     if (lockFile) if (![lockFile unlock]) return NO;    // unlock if needed
  103.     fileOpen = NO;
  104.     return YES;
  105. }
  106.  
  107. - _printRepeats
  108. {
  109.     if (repeats) {
  110.         fprintf(file, "Last line repeated %d time%s\n", repeats,
  111.                 ((repeats == 1) ? "." : "s."));
  112.     }
  113.     [self _newLine];
  114.     return self;
  115. }
  116.  
  117. - (BOOL)appendToLogFile:aString andFlush:(BOOL)flushFlag
  118. {
  119.     if (!fileOpen) return NO;
  120.     // if the file is open, then we should have the lock.
  121.     // however, the user can get around our mechanism if they want, so
  122.     // we'd best check anyway, just to be sure.
  123.     if (lockFile && !special) if (![lockFile haveLock]) return NO;
  124.     // flushing will force a write; not flushing allows us to "compress"
  125.     // log messages by printing only number of repeats.
  126.     if (lastLine && !flushFlag) { // have a previous line, see if it repeats...
  127.         if ([lastLine isEqual:aString]) { // same as before
  128.             repeats++;
  129.             return YES; // don't print; keep tallying
  130.     }    }
  131.     // if got here, the log line is different than last time.
  132.     [self _printRepeats];
  133.     fprintf(file, "%s", [aString stringValue]);
  134.     lastLine = [aString copy];
  135.     if (flushFlag) if (fflush(file) == EOF) return NO;
  136.     return YES;
  137. }
  138.  
  139. - usestdout
  140. {
  141.     [self setFileName:[[DAYString alloc] initString:"stdout"]];
  142.     special = YES;
  143.     fileOpen = YES;
  144.     file = stdout;
  145.     return self;
  146. }
  147.  
  148. - usestderr
  149. {
  150.     [self setFileName:[[DAYString alloc] initString:"stderr"]];
  151.     special = YES;
  152.     fileOpen = YES;
  153.     file = stderr;
  154.     return self;
  155. }
  156.  
  157. - (FILE *)file { if (fileOpen) return file; else return NULL; }
  158. - (BOOL)fileIsOpen { return fileOpen; }
  159. - (BOOL)special { return special; }
  160. - lockFile { return lockFile; }
  161.  
  162. - copy
  163. {    // copies do not have locks or open logs... only original can!
  164.     id myCopy = [[DAYLogFile alloc] init];
  165.     [myCopy setFileName:fileName];
  166.     [myCopy setLockFile:[lockFile copy]];
  167.     return myCopy;
  168. }
  169.  
  170. - read:(NXTypedStream *)stream
  171. {
  172.     [super read:stream];
  173.     fileName = NXReadObject(stream);
  174.     lockFile = NXReadObject(stream);
  175.     return self;
  176. }
  177.  
  178. - write:(NXTypedStream *)stream
  179. {
  180.     [super write:stream];
  181.     NXWriteObject(stream, fileName);
  182.     NXWriteObject(stream, lockFile);
  183.     return self;
  184. }
  185.  
  186. // NXTransport protocol implementation:
  187. - encodeUsing:(id <NXEncoding>)portal
  188. {
  189.     [portal encodeObjectBycopy:fileName];
  190.     [portal encodeObjectBycopy:lockFile];
  191.     return self;
  192. }
  193.  
  194. - decodeUsing:(id <NXDecoding>)portal
  195. {
  196.     fileName = [portal decodeObject];
  197.     lockFile = [portal decodeObject];
  198.     return self;
  199. }
  200.  
  201. - encodeRemotelyFor:(NXConnection *)connection
  202.     freeAfterEncoding:(BOOL *)flagp isBycopy:(BOOL)isByCopy
  203. {
  204.     if (isByCopy) {
  205.         *flagp = NO; // object will copy.
  206.         return self; //encode object (copy it)
  207.     }
  208.     *flagp = NO; // object will copy.
  209.     // super will encode the proxy otherwise
  210.     return [super encodeRemotelyFor:connection
  211.                 freeAfterEncoding:flagp isBycopy:isByCopy];
  212. }
  213.  
  214. - free
  215. {
  216.     if (fileOpen) [self closeFile];
  217.     [lockFile free];
  218.     [fileName free];
  219.     return [super free];
  220. }
  221.  
  222. @end
  223.